package com.hmall.trade.listeners;

import cn.hutool.core.util.StrUtil;
import com.hmall.api.trade.po.Order;
import com.hmall.common.constant.MqConstants;
import com.hmall.trade.service.IOrderService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.ExchangeTypes;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.Exchange;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.QueueBinding;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

/**
 * 监听 MQ 队列
 *
 * @author Zhy
 * @version 1.0
 * @date 2025-03-20 18:08
 */
@Component
@Slf4j
@RequiredArgsConstructor
public class TradeListener {

	private final IOrderService orderService;

	@RabbitListener(
		bindings = @QueueBinding(
			value = @Queue(value = MqConstants.PAY_SUCCESS_QUEUE, durable = "true"), exchange = @Exchange(value = MqConstants.PAY_EXCHANGE_NAME, type = ExchangeTypes.DIRECT), key = MqConstants.PAY_SUCCESS_KEY))
	public void handleTradePaySuccessQueue(String orderId) {
		log.info("支付订单号: {}", orderId);
		if (StrUtil.isNotBlank(orderId)) {
			orderService.markOrderPaySuccess(Long.valueOf(orderId));
		}
	}

	/**
	 * 超时 30 分钟未支付的订单，自动取消订单
	 * <p>
	 * RabbitListener：是 MQ 提供的注解，用于监听队列，并自动调用相应的方法
	 *     QueueBinding：用于绑定队列和交换机，指定 routing key
	 *         value：队列名称
	 *         exchange：交换机名称
	 *         key：routing key
	 * handleNoPaySuccessQueue：是处理队列消息的方法，参数是 Message 对象，用于获取消息内容
	 */
	@RabbitListener(
		bindings = @QueueBinding(
			value = @Queue(value = "trade.dead.order.queue", durable = "true"), exchange = @Exchange(value = "trade.delay.dead.exchange", type = ExchangeTypes.DIRECT), key = "dead.ttl"))
	public void handleNoPaySuccessQueue(Message message) {
		byte[] body = message.getBody();
		String orderId = new String(body);
		log.info("超时未支付订单号: {}", orderId);
		if (StrUtil.isNotBlank(orderId)) {
			// 只有订单状态为 1 的才可以将订单状态设置为 5，表示订单超时未支付
			orderService.lambdaUpdate()
				.eq(Order::getId, Long.valueOf(orderId))
				.eq(Order::getStatus, 1)
				.set(Order::getStatus, 5)
				.update();
		}
	}

}
